Bingo, Computer Graphics & Game Developer

冲量解决方案

1.在一个物理引擎当中一个物体对象通常有三个自由度 分别是xy轴上的自由平移和旋转

2.两物体碰撞 恢复系数取决于小的那个物体

3.冲量 = 动量改变量

Impulse=massVelocityImpulse=mass*Velocity

Velocity=ImpulsemassVelocity=Impulsemass

V=V+(jn)massV' = V + \frac{(j * n )}{mass}

此处的(jn)mass\frac{(j * n )}{mass} 表示速度改变量

4.这里的VABV_{AB}实质上是在应用了恢复系数之后的VabV_{ab}'

VABn=e(VBVA)nV_{AB}' n = e (V_B - V_A)*n

原来式子中的负号是有误的

因此后面在使用这三个式子来推导最终结果的时候就可以理解了

VA=VA+(jn)massAV'_A=V_A+\frac{(j*n)}{mass_A}

VB=VB(jn)massBV'_B=V_B-\frac{(j*n)}{mass_B}

5.正确的推导

(VBVA(jn)/massA(jn)/massB)n=e(VBVA)n(V_B-V_A-(j n) / mass_A-(j n) / mass_B)n= e (V_B-V_A) * n

(VBVA)nj((jn)/massA+(jn)/massB)ne(VBVA)n=0(V_B-V_A) n-j((j n) / mass_A+(j n)/ mass_B)n-e (V_B-V_A) * n= 0

(1+e)((VBVA)n)+j((jn)massA+(jn)massB)n=0(1+e)((V_B-V_A) n)+j (\frac{(j n)}{mass_A} + \frac{(j n)}{mass_B}) * n=0

j=(1+e)((VBVA)n)(1/massA+1/massB)j=-\frac{(1+e)((V_B-V_A) * n)}{(1/mass_A+1/mass_B)}

原本的计算方式中虽然最终结果是正确的 但是推导过程中两次负号都出错 因此导致结果正确但是推导不正确的情况

6.预计算质量的倒数是非常有必要的

 A.inv_mass = 1 / A.mass

将 j 根据质量大小来分配给两个对象

mass_sum = A.mass + B.mass
float ratio = A.mass / mass_sum
A.velocity -= ratio * impulse

ratio = B.mass / mass_sum
B.velocity += ratio * impulse

PS:这个步骤 实质上就是ResolveCollision()这里也能看出来质量的倒数的重要性

7.位置修正的本质就是将两个互相碰撞的物体(在应用了冲量之后) 在其碰撞法线上移动一定距离(渗透距离的一定百分比 通常在20%~80%之间 作者推荐使用40%)